#ifndef __DTLS_TRANSPORT_H
#define __DTLS_TRANSPORT_H
#include <memory>
#include <string>
#include <rtc_base/ssl_stream_adapter.h>
#include <rtc_base/buffer_queue.h>
#include <rtc_base/stream.h>
#include <rtc_base/rtc_certificate.h>
#include "ice/ice_transport_channel.h"
namespace xrtc
{
    enum class DtlsTransportState
    {
        kNew,
        kConnecting,
        kConnected,
        kClosed,
        kFailed,
        kNumValues
    };
    class StreamInterfaceChannel : public rtc::StreamInterface
    {

    public:
        StreamInterfaceChannel(IceTransportChannel *ice_channel);
        bool OnReceivedPacket(const char *data, size_t size);
        rtc::StreamState GetState() const override;
        rtc::StreamResult Read(void *buf, size_t buffer_len, size_t *read, int *error) override;
        rtc::StreamResult Write(const void *buf, size_t buffer_len, size_t *read, int *error) override;
        void Close() override;

    private:
        IceTransportChannel *ice_channel_;
        rtc::BufferQueue _packets;
        rtc::StreamState state_ = rtc::SS_OPEN;
    };
    class DtlsTransport : public sigslot::has_slots<>
    {

    public:
        DtlsTransport(IceTransportChannel *ice_channel);
        ~DtlsTransport();
        std::string ToString();
        const std::string& TransportName() { return ice_channel_->TransportName(); }
        IceCandidateComponent Component() { return ice_channel_->Component(); }
        IceTransportChannel* IceChannel() { return ice_channel_;}
        bool SetLocalCertificate(rtc::RTCCertificate *cert);
        bool SetRemoteFingerprint(const std::string &digest_alg, const uint8_t *digest, size_t digest_len);
        bool IsRtpPacket(const char *buf, size_t len);
        DtlsTransportState DtlsState() { return dtls_state_;}
        bool IsDtlsActive() {return dtls_active_;}
        bool Writable() {return writable_;}
        bool GetSrtpCryptoSuite(int* selected_crypto_suite);
        bool ExportKeyingMeterial(const std::string& label,const uint8_t* context,size_t context_len,
            bool use_context,uint8_t * result,size_t  result_len);
        int SendPacket(const char*data,size_t len);

        sigslot::signal2<DtlsTransport *, DtlsTransportState> SignalDtlsState;
        sigslot::signal1<DtlsTransport *> SignalWritableState;
        sigslot::signal1<DtlsTransport *> SignalReceivingState;
        sigslot::signal4<DtlsTransport *, const char *, size_t, int64_t> SignalReadPacket;
        sigslot::signal1<DtlsTransport *> SignalClosed;

    private:
        void OnReadPacket(IceTransportChannel * /*channel*/, const char *bud, size_t len, int64_t ts);
        void MaybeStartDtls();
        bool SetupDtls();
        void SetDtlsState(DtlsTransportState state);
        void SetWritableState(bool writable);
        bool HandleDtlsPacket(const char *data, size_t size);
        void OnWritableState(IceTransportChannel *channel);
        void OnDtlsHandshakeError(rtc::SSLHandshakeError err);
        void OnDtlsEvent(rtc::StreamInterface *dtls, int sig, int error);
        void OnReceivingState(IceTransportChannel *channel);
        void SetReceiving(bool receiving);

    private:
        IceTransportChannel *ice_channel_;
        DtlsTransportState dtls_state_ = DtlsTransportState::kNew;
        bool receiving_ = false;
        bool writable_ = false;
        bool dtls_active_ = false; // 证书状态
        std::unique_ptr<rtc::SSLStreamAdapter> dtls_;
        rtc::Buffer cached_client_hello_;
        rtc::RTCCertificate *local_certificate_ = nullptr;
        StreamInterfaceChannel *downward_ = nullptr;
        std::string remote_fingerprint_alg_;
        rtc::Buffer remote_fingerprint_value_;
        std::vector<int> srtp_ciphers_;
    };

} // namepsace xrtc

#endif